فرکانس شمار با دقت بالا برای میکروکنترولر‌های نوع PIC

یکی از ابزاری که در روی میز کار علاقمندان به الکترونیک وجود دارد و یا باید وجود داشته باشد فرکانس‌ شمار است.
در این نوشتار سعی خواهم کرد برای شما مداری را توضیح بدهم که بتوانید با حداقل هزینه دارای یک دستگاه سنج فرکانس با دقت خیلی خوبی باشید. قسمت اصلی یا قلب این دستگاه در نرم‌افزار آن است. این نرم‌افزار برای میکروکنترلر از نوع PIC نوشته شده ولی شما میتوانید در واقع آنرا برای انواع دیگر هم استفاده کنید بشرطی که آنها دارای 2 تایمر یکی 8 بیتی و دیگری 16 بیتی باشند و دیگر آنکه دارای قابلیت اینترراپت (interrupt) هم باشند.
نکته مهم دیگر آنکه تایمر 8 بیتی آنان باید یک ورودی خارجی برای شمردن داشته باشد.
تا حدی که من میدانم اکثر میکروکنترلها دارای چنین مشخصاتی هستند.
در میکروکنترلرهای نوع PIC تایمر0 آنان قادر است پالسهایی را با حداقل پریود برابر با 20 نانو ثانیه را بکار ببرد که این معادل سیگنال 50 مگاهرتز میباشد.
در این مدار از زمان سنج صفر(Timer 0) برای شمارش فرکانس و از زمان سنج یک (Timer 1) برای تعیین زمان اندازه‌گیری (برابر 1 ثانیه) استفاده شده است.
برای ضبط مقدار فرکانس ورودی از 4 بایت (32 بیت) استفاده شده است.(هر چند که برای نشان دادن مقدار عددی 50000000 ما حداکثر به 26 بیت نیاز داریم ولی برای سهولت در نوشتن نرم‌افزار از 32 بیت استفاده شده است)

توضیح نرم افزار
این تصویر روش اندازه‌گیری را نشان میدهد.

مدار

روش انداره گیری بدین شرح است که در فاصله زمانی یک ثانیه تعداد سرریز شدن Timer 0 را در Interrupt به Byte دوم و سوم و چهارم منتقل میکنیم و در پایان وقت مقداری را که در آن(Timer 0) است را به اولین بایت که دارای کمترین ارزش عددی است منتقل میکنیم. در پایان دارای یک عدد Binar 32 Bit خواهیم بود که تعداد فرکانس را نشان میدهد. این عدد تبدیل به Paket-BCD میشود و به LCD فرستاده میشود.
در واقع این 31 سطر پایین مهمترین یا اساسی‌ترین قسمت کد هستند که در قسمت حافظه داخلی مربوط به اینترراپت قرار میگیرند.
بقیه کد مربوط به تنظیمات, تبدیل عدد باینر به BCD, کالیبره‌سازی, تنظیم و کنترل نشاندهنده LCD میباشد که نسبت به نوع PIC و LCD میتواند تغییر کند.
در برنامه فقط باید بطور مرتب بیت [ Show_Val ] تست شود و اگر روشن شده باشد عدد 32 بیت باینر را به BCD تبدیل کرده, به نشاندهنده فرستاده و دوباره شروع به اندازه‌گیری می‌نماییم.
   
;#################################################
		ORG     0x004
	
1.		btfss	INTCON,T0IF
2.		goto	TMR1_IRQ
	TMR0_IRQ:
3.		bcf	INTCON,T0IF
4.		incfsz	B2Tmp,F
5.		retfie
6.		incfsz	B3Tmp,F
7.		retfie
8.		incf	B4Tmp,F
9.		retfie
	TMR1_IRQ:
10.		bcf	PIR1,TMR1IF
11.		decfsz	TMR1_Count,F
12.		retfie
13.		movf	TMR0,W
14.		movwf	Bin1
15.		btfsc	INTCON,T0IF
16.		incf	B2Tmp,F
17.		bcf	INTCON,T0IF
18.		bcf	INTCON,T0IE
19.		bcf	T1CON,TMR1ON
20.		movf	B2Tmp,W
21.		movwf	Bin2
22.		clrf	B2Tmp
23.		movf	B3Tmp,W
24.		movwf	Bin3
25.		clrf	B3Tmp
26.		movf	B4Tmp,W
27.		movwf	Bin4
28.		clrf	B4Tmp
29.		bsf	Bit_Flag,Show_Val
30.		retfie
;#################################################
 
  
توضیح سطور:
سطر 1 - منبع اینترراپت تست میشود, اگر منبع تایمر0 باشد به سطر 3 وگرنه به سطر 2 پرش انجام میگیرد. این دستور اگر شامل پرش شود به 2 سیکل وگرنه به 1 سیکل برای اجرا نیاز دارد.(1 یا 2 سیکل)
سطر 2 - پرش به محل اینترراپت تایمر1. (2 سیکل)
سطر 3 - باید بیت نشاندهنده اینترراپت تایمر0 (interrupt flag)را خاموش کنیم.(1 سیکل)
سطر 4 - از اینجا تا سطر 9 سرریز تایمر0 به 3 بایت منتقل میشود. برای هر بایت تست میشود که آیا خود بایت سرریز شده یا خیر , اگر نشده از اینترراپت خارج شده و اگر خود بایت سرریز شده باشد, سرریز به بایت بعدی منتقل میشود.از این 3 بایت بعنوان دخیره‌کننده میانی استفاده شده. برای این 6 سطر مجموعا به 7 سیکل نیاز است.
در اینجا کد اینترراپت برای تایمر0 بپایان میرسد.
سطر 10 - پاک کردن بیت نشاندهنده اینترراپت برای تایمر1 (1 سیکل)
سطر 11 - تست اینکه آیا زمان بپایان رسیده,یا خیر (2 سیکل)
سطر 12 - زمان بپایان نرسیده, خروج از اینترراپت (2 سیکل) سطر 13 - در اینجا 1 ثانیه بپایان رسیده بنابراین مقدار موجود در تایمر0 را ضبط میکنیم (1 سیکل)
سطر 14 - مقدار تایمر0 به بایت1 منتقل میشود(1 سیکل)
سطر 15 - تست اینکه آیا در حین انجام این دستورات برای تایمر1, تایمر0 سرریز شده؟ اگر آری, مقدار بایت دوم را در سطر 16 اضافه میکنیم.
سطر 16 - از اینجا تا انتها (سطر 30) تاثیری در اندازه‌گیری ندارد فقط تایمر‌ها را نگه میداریم و مقدار انداره‌گیری شده را به 3 بایت اصلی منتقل و بایت‌های میانی را برای اندازه‌گیری بعدی آماده میکنیم.
سطر 30 - برگشت از اینترراپت

بالا بالا

همانطور که دیده میشود با توجه به اینکه برای پرش به اینترراپت به 2 سیکل نیاز است, حداکثر سیکل مورد نیاز برای تایمر0 (در بدترین حالت!) 12 سیکل است.
برای تایمر1 در هر دو حالت, چه در حال شمارش و چه هنگامی که زمان بپایان میرسد به 9 سیکل احتیاج است.
تعیین حداقل فرکانس اوسیلاتور مدار بستگی مستقیم به تاخیرات CPU در اجرای این دستورات در زمان اینترراپت دارد.
چون این 2 حالت هر دو از تاخیرات زمانی تایمر0 کمتر هستند, پس فقط تایمر0 را برای تعیین حداقل فرکانس مدار بکار میبریم.
دلیل این کار این است که در هنگام اجرای دستورات اینترراپت برای تایمر0 و تایمر1 بعلاوه 4 سیکل برای برنامه اصلی نباید تایمر0 2 بار سرریز شود. مجموع تمام اینها 25 سیکل است, بنابراین تایمر0 نباید در طی 12.5 سیکل سرریز شود.
به همین دلیل حداقل فرکانس اوسیلاتور باید اینطور محاسبه شود:
- فرکانس ورودی 50 مگاهرتز , پریود 20 نانو ثانیه
- تایمر0 8 بیت برابر 256
- سیکل داخلی برابر یک چهارم اوسیلاتور مدار

20 nS × 256 = 5,12 µS
5,12 µS ÷ 12,5 = 0,4096 µS
0,4096 µS ÷ 4 = 0,1024 µS = 9,765625 MHz

بنابراین اگر اوسیلاتور مدار کمتر از تقریبا 10 مگاهرتز باشد قادر به اندازه‌گیری صحیح نخواهیم بود و مدار بدرد سطل زباله میخورد.
در عمل بهتر است که ما برای اطمینان مقداری رزرو داشته باشیم!
من اوسیلاتور 16 مگاهرتز را استفاده کردم چون در دسترس بود.
با اوسیلاتور 16 مگاهرتز CPU میتواند حدود 20,48 دستور را اجرا کند تا تایمر0 سرریز شود!
بعد از انتخاب اوسیلاتور باید زمان اندازه‌گیری (1 ثانیه) را بدین صورت محاسبه کنیم:
اگر فرض کنیم که کوارتز یا اوسیلاتور ما ایده‌ال است (اینجا 16 مگاهرتز) پس میدانیم سیکل داخلی برابر با یک چهارم اوسیلاتور یعنی 4000000 سیکل در ثانیه است و سرریز تایمر1 در 65536 سیکل انجام میگیرد.

4000000 ÷ 65536 = 61,03515625
61 × 65536 = 3997696
4000000 - 3997696 = 2304
65536 - 2304 = 63232 = 0xF700

پس اکر ما تعداد 61 سرریز را بشماریم و بعد از آن تایمر1 را با مقدار 0xF700 = 63232 بارگیری (Reload) کنیم در هنگام سرریز بعدی 1 ثانیه زمان سپری شده است. پس در مجموع باید تعداد 62 سرریز تایمر1 را شمرد.
اما عدد محاسبه شده برای بار‌گیری (Relaod) را نمیتوان بدین صورت استفاده کرد, چون در هنگام پایان رسیدن شمارش تا زمان ضبط مقدار تایمر0 مقداری زمان گذشته است! این زمان برابر با 9 سیکل است(تاخیرات برای تایمر1)
بنابر‌این عدد نهایی بارگیری :

63232 - 9 = 63223 = 0xF6F7

این عدد در 2 بایت آخر ( 7E:High value , 7F:Low value) EEPROM ذخیره میشود و در هنگام روشن شدن مدار یا بعد از ریست (Reset) خوانده و در شروع اندازه‌گیری در تایمر1 بار‌گیری میشود.
این تمام اطلاعاتی است که شما برای درست کردن این فرکانس‌سنج به آن احتیاج دارید. شما میتوانید از این قسمت در کلیه مبکروکنترلر‌ها استفاده کنید.
بقیه مطالب مربوط به کنترل نشاندهنده و استفاده از کلید فشاری و دیگر لوازم جانبی که به میکر.کنترلر وصل میشود میتواند با نوع انتخاب شما در کنترولر متفاوت باشد.( فانتزی شما مرزی ندارد!)

بالا پایین

منابع خطای اندازه‌گیری :
اصولا هیچ اندازه‌گیری در این جهان بدون خطا نیست و این مدار نیز از آن مبرا نمی‌باشد ولی همیشه سعی بر این است که مقدار خطا به حداقل برسد.
یکی از این منابع خطا اینجا خود تایمر0 است, اگر به مدار آن در datasheet نگاه کنیم می بینیم که یک مدار سینکرون کردن فرکانس بعد از تقسیم‌کننده قرار دارد که فرکانس ورودی را با اوسیلاتور داخلی سینکرون میکند و به دو flanke مثبت احتیاج دارد و در بدترین حالت در زمان اندازه‌گیری نصف پریود در آغاز و نصف پریود در انتها را از دست میدهیم که این خطای 1 هرتز را در تمام محدوده‌ اندازه‌گیری داریم که این خطای سیستماتیک را نمیشود از بین برد.
دوم اینکه تنها قطعه‌ای که در اندازه‌گیری دخالت دارد فقط میکروکنترلر است و خطای آن به منبع تغذیه و اوسیلاتور آن وابسته است.
تغییرات منبع تغذیه حدود 0.75 ولت ( 4.5 تا 5.25) اثری در کارکرد آن ندارد.
اما خود اوسیلاتور دارای خطای فرکانس است که معمولا توسط سازنده بصورت +/- 100 ppm داده میشود. (عدد 100 مثال است ولی به واقعیت نزدیک است)
پس اوسیلاتور ما دارای یک خطای ذاتی برابر با 1600 +/- هرتز است.
تغیرات دیگر فرکانس اوسیلاتور مربوط به پیرشدن آن, تغیرات دما و تغیرات منبع تغذیه است.
برای جبران کردن این خطاها میتوان از اوسیلاتورهایی با کیفیت بالا استفاده کرد که قیمت آنان نیز بالا است.
همچنین میتوان از یک سیگنال رفرنس مانند GPS یا سیگنال رادیویی ساعت (اگر در ایران قابل دریافت باشد!) برای سینکرون کردن اوسیلاتور مدار استفاده کرد که تمام این روشها هزینه و کار زیادی میبرد و برای این پروژه مناسب نیست.

بدون انجام این روشها هم این مدار دارای کیفیت بسیار خوبی برای کار آماتوری میباشد.

آسانترین روش اینست که اگر از کوارتز استفاده میکنیم باید خازنی را که در پایه OSCIN قرار دارد را با یک خازن تریمر با ظرفیتی تقریبا معادل آن حایگزین نموده و با تنظیم آن به فرکانس دقیق نزدیک شویم.
روش دیگر توسط نرم‌افزار است که من اینجا استفاده کرده‌ام. طرز کار آن بدین صورت است که توسط یک فرکانس ژنراتور دقیق یک فرکانس را به ورودی وصل کرده و توسط یک کلید فشاری زمان پایه (1 ثانیه) را هر بار به‌اندازه یک سیکل تغییر میدهیم.
این تغییرات در EEPROM دخیره شده و تا زمانی که دوباره تغییر نکند پایدار میماند.
چون در این نرم‌افزار انتخاب تقسیم‌کننده فرکانس بطور اتوماتیک انجام میگیرد, در زمان کالیبره‌کردن, نسبت به مقدار فرکانسی که توسط ژنراتور به مدار وصل شده و مقدار تقسیم‌کننده, فرکانس تغییر داده شده نشان داده میشود.
بعنوان مثال اگر فرکانس ژنراتور 16 مگاهرتز باشد, تقسیم‌کننده برابر 8 است و هر فشار روی کلید, تنظیم به اندازه +/- 4 Hz انجام میشود ولی فرکانس نشانداده شده در قدم‌های 8 هرتزی نشان داده میشود.

این مدار عملی آن که با یک PIC از نوع 8 پایه درست و آزمایش شده است.

(برای بزرگتر شدن روی عکس کلیک کنید)


این فایل فشرده FCuont Project حاوی تمام فایلهای مربوط به این مدار میباشد.
در زیر پوشه output فایل FCount.hex را برای بارگیری پیدا میکنید.


کالیبره‌ سازی :
در این مدار بدلیل استفاده از PIC12F629/675 انتخاب زیادی در تعداد پایه‌ها نداریم, بهمین دلیل عمل کالیبره‌سازی توسط یک کلید فشاری انجام میشود.
با فشار دادن کلید کلمه Calibration در سطر اول نشان داده میشود و در سطر دوم 3 گزینه ( Down, Up, Cancel ) نشان داده میشود. هر کدام از این 3 گزینه تقریبا مدت 1 ثانیه بطور متناوب نشان داده میشود تا انتخاب شوند.
با انتخاب Cancel از حالت کالیبره‌سازی خارج میشویم.
اگر گزینه‌های Down یا Up انتخاب شوند, باید در مدت 1 ثانیه کلید فشار داده شود تا فرکانس بطرف بالا یا پایین تنظیم شود, در این هنگام تعداد فشاردادن کلید بصورت 1+ یا 1- در همان سطر نشان داده میشود. اگر در مت 1 ثانیه کلید فشار داده نشود به Menu انتخاب باز میگردد و برای خروج باید Cancel انتخاب شود.
در این نوشتار من از توضیح در مورد باقیمانده کد خودداری میکنم چون توضیحات, نسبت به نوع LCD متفاوت خواهد بود.
برای دانستن ,شناخت و روش کنترل LCD میتوانید به کاربرد LCD در مدارات خود مراجعه کنید.

برای اندازه گیری فرکانس های بالاتر از 50 MHz فقط باید بک تقسیم کننده فرکانس را جلوی ورودی قرار داد.
در هنگام طرح فیبرچاپی حتما رعابت نکات لازم را در مورد فرکانس‌های بالا در نظر داشته باشید.
امیدوارم که این پروژه برای شما مفید باشد. اگر سوالی یا پیشنهادی دارید از قسمت نظر شما استفاده کنید.

بالا